const { toString } = Object.prototype

/**
 * 判断目标对象是否包含指定的key
 * @param {Object} target
 * @param {Object} key
 */
export function hasOwnProp(target, key) {
  return Object.prototype.hasOwnProperty.call(target, key)
}

export function _is(val, type) {
  return toString.call(val) === `[object ${type}]`
}

// 验证是不是H5端
export const isH5 = () => {
  let value = true
  // #ifndef H5
  value = false
  // #endif
  return value
}

export const isMp = () => {
  let value = true
  // #ifndef MP-WEIXIN
  value = false
  // #endif
  return value
}

// 验证是不是H5开发模式
export const isH5Dev = () => {
  return isH5() && process.env.NODE_ENV === 'development'
}

export const isWx = () => {
  if (isH5()) {
    var ua = window.navigator.userAgent.toLowerCase()
    if (/micromessenger/i.test(ua) || /wechatdevtools/i.test(ua)) {
      return true
    }
  }
  return false
}

// 验证金额
export const isAmount = (value, noZero = false) => {
  if (noZero && value <= 0) {
    return false
  } else {
    let reg = /((^[1-9]\d*)|^0)(\.\d{0,2}){0,1}$/
    return reg.test(value)
  }
}

// 验证手机
export const isMobile = value => {
  var reg = /^[1]([3-9])[0-9]{9}$/
  return reg.test(value)
}

// 验证手机和座机
export const isPhone = value => {
  var reg = /^([0-9]{3,4}-?)?[0-9]{7,8}$/
  return isMobile(value) || reg.test(value)
}

// 验证身份证
export const isID = value => {
  var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
  return reg.test(value)
}

export const isEmail = value => {
  var reg = /^[A-Za-zd0-9] ([-_.][A-Za-zd] )*@([A-Za-zd] [-.]) [A-Za-zd]{2,5}$/
  return reg.test(value)
}

export function isDef(val) {
  return typeof val !== 'undefined'
}

export function isUnDef(val) {
  return !isDef(val)
}

export function isObject(val) {
  return val !== null && _is(val, 'Object')
}

export function isEmpty(val) {
  if (!val) {
    return true
  }
	
  if (isArray(val) || isString(val)) {
    return val.length === 0
  }

  if (val instanceof Map || val instanceof Set) {
    return val.size === 0
  }

  if (isObject(val)) {
    return Object.keys(val).length === 0
  }

  return false
}

export function isDate(val) {
  return _is(val, 'Date')
}

export function isNull(val) {
  return val === null
}

export function isNullAndUnDef(val) {
  return isUnDef(val) && isNull(val)
}

export function isNullOrUnDef(val) {
  return isUnDef(val) || isNull(val)
}

export function isNumber(val) {
  return _is(val, 'Number')
}

export function isPromise(val) {
  return (
    _is(val, 'Promise') &&
    isObject(val) &&
    isFunction(val.then) &&
    isFunction(val.catch)
  )
}

export function isString(val) {
  return _is(val, 'String')
}

export function isFunction(val) {
  return typeof val === 'function'
}

export function isBoolean(val) {
  return _is(val, 'Boolean')
}

export function isRegExp(val) {
  return _is(val, 'RegExp')
}

export function isArray(val) {
  return val && Array.isArray(val)
}

export function isWindow(val) {
  return typeof window !== 'undefined' && _is(val, 'Window')
}

export function isIos() {
  const ua = navigator.userAgent
  return /ip(hone|od|ad)/i.test(ua)
}

export function isElement(val) {
  return isObject(val) && !!val.tagName
}

export function isMap(val) {
  return _is(val, 'Map')
}

export const isServer = () => typeof window === 'undefined'

export const isClient = () => !isServer()

export function isUrl(path) {
  // @ts-ignore
  const reg =
    /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
  return reg.test(path)
}

